package com.gxa.jd.service.impl;

import com.gxa.jd.es.EsHotel;
import com.gxa.jd.es.respository.HotelRepository;
import com.gxa.jd.service.HotelSearchService;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class HotelSearchServiceImpl implements HotelSearchService {

    @Autowired
    private HotelRepository hotelRepository;

    @Override
    public Page<EsHotel> findPage(String search, double latitude, double longitude, String distance, Pageable pageable) {

        // 实现了SearchQuery接口，用于组装QueryBuilder和SortBuilder以及Pageable等
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        // 分页
        nativeSearchQueryBuilder.withPageable(pageable);

        // 间接实现了QueryBuilder接口
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();


        // 以某点为中心，搜索指定范围
        GeoDistanceQueryBuilder distanceQueryBuilder = new GeoDistanceQueryBuilder("geo");
        distanceQueryBuilder.point(latitude, longitude);

        // 定义查询单位：公里
        distanceQueryBuilder.distance(distance, DistanceUnit.KILOMETERS);
        boolQueryBuilder.filter(QueryBuilders.matchQuery("name", search));
        boolQueryBuilder.filter(distanceQueryBuilder);
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);

        // 按距离升序
        GeoDistanceSortBuilder distanceSortBuilder =
                new GeoDistanceSortBuilder("geo", latitude, longitude);
        distanceSortBuilder.unit(DistanceUnit.KILOMETERS);
        distanceSortBuilder.order(SortOrder.ASC);
        nativeSearchQueryBuilder.withSort(distanceSortBuilder);

        return hotelRepository.search(nativeSearchQueryBuilder.build());
    }

    @Override
    public EsHotel findHotelById(Integer id) {
        Optional<EsHotel> optional = hotelRepository.findById(id);
        if(optional!=null){
            return optional.get();
        }
        return null;
    }
}
